﻿using ClusteringProblem.Model;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;

namespace ClusteringProblem.DataImport
{
    class WineDataReader : DataReaderStrategy
    {
        private Dataset dataset;

        public override List<ClusteringProblem.Model.Object> ReadData(string filePath, bool isNormilizeData)
        {
            dataset = new Dataset();
            List<Tuple<string, List<double>>> data = GetData(filePath);

            if (isNormilizeData)
            {
                data = NormalizeData(data, -1, 1);
            } 
            
            int id = 0;
            foreach (var x in data)
            {
                ClusteringProblem.Model.Object obj = new ClusteringProblem.Model.Object()
                {
                    GroupID = x.Item1,
                    ID = id
                };
                int order = 0;

                foreach (var y in x.Item2)
                {
                    Value value = new Value()
                    {                        
                        VectorOrder = order,
                        Feature = y
                    };

                    obj.Values.Add(value);
                    obj.Features += value.Feature + ";";
                }

                dataset.Objects.Add(obj);

                id++;
                order++;
            }

            return dataset.Objects;  
            
        }

        private List<Tuple<string, List<double>>> NormalizeData(List<Tuple<string, List<double>>> data, int newMin, int newMax)
        {
            MinMaxPair[] normalizationTable = new MinMaxPair[data[0].Item2.Count];

            for (int i = 0; i < normalizationTable.Count(); ++i)
                normalizationTable[i] = new MinMaxPair();

            double tmp = 0.0F;

            foreach (var obj in data)
                for (int i = 0; i < obj.Item2.Count; ++i)
                {
                    tmp = obj.Item2[i];

                    if (normalizationTable[i].Max < tmp)
                        normalizationTable[i].Max = tmp;

                    if (normalizationTable[i].Min > tmp)
                        normalizationTable[i].Min = tmp;
                }

            foreach (var obj in data)
                for (int j = 0; j < obj.Item2.Count; ++j)
                {
                    obj.Item2[j] = (obj.Item2[j] - normalizationTable[j].Min) / (normalizationTable[j].Max - normalizationTable[j].Min);
                    obj.Item2[j] = (obj.Item2[j] * (newMax - newMin)) + newMin;
                }

            return data;
        }

        private List<Tuple<string, List<double>>> GetData(string filePath)
        {
            List<Tuple<string, List<double>>> data = new List<Tuple<string, List<double>>>();

            using (StreamReader reader = new StreamReader(filePath))
            {
                string line = null;

                while ((line = reader.ReadLine()) != null)
                {
                    string[] splitted = line.Split(',');

                    Tuple<string, List<double>> singleItem = new Tuple<string, List<double>>(splitted[0], new List<double>());

                    // od i = 1 bo 0 to Id grupy
                    for (int i = 1; i < splitted.Count(); i++)
                    {
                        singleItem.Item2.Add(double.Parse(splitted[i], CultureInfo.InvariantCulture));
                    }

                    data.Add(singleItem);
                }
            }

            return data;
        }        
    }
}
